using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace CollabApp.Domain.Entities.Auth;

/// <summary>
/// 用户统计实体 - 存储用户的游戏数据统计信息
/// 继承BaseEntity，支持软删除和时间戳功能
/// </summary>
[Table("user_statistics")]
public class UserStatistics : BaseEntity
{
    /// <summary>
    /// 关联用户ID - 外键，指向Users表，一对一关系
    /// </summary>
    [Required]
    [Column("user_id")]
    public Guid UserId { get; private set; }

    /// <summary>
    /// 总游戏场次 - 用户参与的游戏总数
    /// </summary>
    [Column("total_games")]
    public int TotalGames { get; private set; } = 0;

    /// <summary>
    /// 胜利次数 - 用户获得第一名的次数
    /// </summary>
    [Column("wins")]
    public int Wins { get; private set; } = 0;

    /// <summary>
    /// 失败次数 - 用户未获得第一名的次数
    /// </summary>
    [Column("losses")]
    public int Losses { get; private set; } = 0;

    /// <summary>
    /// 胜率 - 胜利次数占总游戏场次的百分比
    /// </summary>
    [Column("win_rate")]
    [Precision(5, 2)]
    public decimal WinRate { get; private set; } = 0;

    /// <summary>
    /// 总积分 - 用户累计获得的积分（根据排名计算）
    /// </summary>
    [Column("total_score")]
    public int TotalScore { get; private set; } = 0;

    /// <summary>
    /// 最高占领面积 - 用户在单局游戏中的最佳成绩
    /// </summary>
    [Column("max_area")]
    [Precision(10, 2)]
    public decimal MaxArea { get; private set; } = 0;

    /// <summary>
    /// 总游戏时长 - 用户累计游戏时间（秒）
    /// </summary>
    [Column("total_play_time")]
    public int TotalPlayTime { get; private set; } = 0;

    /// <summary>
    /// 当前排名 - 用户在全服排行榜中的位置
    /// </summary>
    [Column("current_rank")]
    public int CurrentRank { get; private set; } = 0;

    /// <summary>
    /// 历史最高排名 - 用户曾经达到的最高排名
    /// </summary>
    [Column("highest_rank")]
    public int HighestRank { get; private set; } = 0;

    // ============ 构造函数 ============

    /// <summary>
    /// 无参构造函数 - EF Core 必需
    /// </summary>
    private UserStatistics() { }

    /// <summary>
    /// 私有构造函数 - 仅限工厂方法调用
    /// </summary>
    /// <param name="userId">关联用户ID</param>
    private UserStatistics(Guid userId)
    {
        UserId = userId;
        TotalGames = 0;
        Wins = 0;
        Losses = 0;
        WinRate = 0;
        TotalScore = 0;
        MaxArea = 0;
        TotalPlayTime = 0;
        CurrentRank = 0;
        HighestRank = 0;
    }

    // ============ 导航属性 ============
    
    /// <summary>
    /// 关联的用户实体 - 一对一关系
    /// </summary>
    [ForeignKey("UserId")]
    public virtual User User { get; set; } = null!;

    // ============ 工厂方法 ============

    /// <summary>
    /// 创建新的用户统计记录 - 工厂方法
    /// </summary>
    /// <param name="userId">关联用户ID</param>
    /// <returns>新的用户统计实例</returns>
    public static UserStatistics CreateForUser(Guid userId)
    {
        if (userId == Guid.Empty)
            throw new ArgumentException("用户ID不能为空", nameof(userId));

        return new UserStatistics(userId);
    }

    // ============ 业务方法 ============

    /// <summary>
    /// 更新游戏结果统计
    /// </summary>
    /// <param name="isWin">是否胜利</param>
    /// <param name="gameScore">本局积分</param>
    /// <param name="area">本局占领面积</param>
    /// <param name="playTimeSeconds">本局游戏时长（秒）</param>
    public void UpdateGameResult(bool isWin, int gameScore, decimal area, int playTimeSeconds)
    {
        TotalGames++;
        if (isWin)
            Wins++;
        else
            Losses++;

        // 重新计算胜率
        WinRate = TotalGames > 0 ? (decimal)Wins / TotalGames * 100 : 0;

        TotalScore += Math.Max(0, gameScore);
        TotalPlayTime += Math.Max(0, playTimeSeconds);

        // 更新最高占领面积
        if (area > MaxArea)
            MaxArea = area;
    }

    /// <summary>
    /// 更新排名信息
    /// </summary>
    /// <param name="newRank">新排名</param>
    public void UpdateRank(int newRank)
    {
        if (newRank <= 0)
            throw new ArgumentException("排名必须大于0", nameof(newRank));

        CurrentRank = newRank;

        // 更新历史最高排名（排名数字越小越好）
        if (HighestRank == 0 || newRank < HighestRank)
            HighestRank = newRank;
    }

    /// <summary>
    /// 重置统计数据
    /// </summary>
    public void ResetStatistics()
    {
        TotalGames = 0;
        Wins = 0;
        Losses = 0;
        WinRate = 0;
        TotalScore = 0;
        MaxArea = 0;
        TotalPlayTime = 0;
        CurrentRank = 0;
        HighestRank = 0;
    }
}
